/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package name_service;

import java.io.IOException;
import java.io.Serializable;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import mware_lib.ObjectRef;
import mware_lib.tcp.Connection;
import mware_lib.tcp.Server;

/**
 *
 * @author zero.one
 */
public class GlobalNS {

    int port;
    Server server;
    Connection clientSocket; //<<< Der globale Namensdienst hat mehrere gleichzeitig offene Verbindungen, das hier lässt nur eine zu
    //    und schließt die Verbindung nicht korrekt, wenn eine neue in der Zwischenzeit geöffnet wurde.
    String message;
    Map<String, ObjectRef> objectMap = new ConcurrentHashMap<>();
    ConnectionHandler conHan;

    public GlobalNS(int port) {
      
        this.port = port;
        try {
            this.server = new Server(port);
            System.out.println("Namensdienst auf Port " + port + " gestartet");
        } catch (IOException ex) {
            throw new RuntimeException("Port not available");
        }
    }

    public ObjectRef resolve(String message) {
        return objectMap.get(this.getRegistryNameFromString(message));
    }

    public void register(String message, SocketAddress remoteEndpoint) {
        //Flag, object, RegName
        String[] strArr = message.split("/");
        //hostName + ":" + port + ":" + listIndex;
        String[] objToRegister = this.getObjectFromString(message);
        //ObjectRef objRef = new ObjectRef(objToRegister[0], Integer.parseInt(objToRegister[1]), Integer.parseInt(objToRegister[2]));
        ObjectRef objRef = new ObjectRef(((InetSocketAddress) remoteEndpoint).getHostName(),
                Integer.parseInt(objToRegister[1]), Integer.parseInt(objToRegister[2]));
        String registryName = strArr[2];

        objectMap.put(registryName, objRef);
    }

    //in neuem Thread starten
    public void receive() {
        while (true) {
            try {
                clientSocket = server.getConnection();
                conHan = new ConnectionHandler(clientSocket, this);
                new Thread(conHan).start();
            } catch (IOException ex) {
                throw new RuntimeException(ex.getMessage());//"Eingehenede Verbindung konnte nicht geöffnet werden");
            }
        }
    }

    private String[] getObjectFromString(String message) {
        //Flag, object, RegName
        String[] strArr = message.split("/");
        int flag = Integer.parseInt(strArr[0]);
        //hostName + ":" + port + ":" + listIndex;
        String[] objToRegister = strArr[1].split(":");
        return objToRegister;
    }

    private String getRegistryNameFromString(String message) {
        String[] resultArr = message.split("/");
        return resultArr[2];
    }

    public static void main(String... args) { 
      if (args.length != 1)
        System.out.println("Usage: java -cp . name_service.GlobalNS <port>");
      else
        new GlobalNS(Integer.parseInt(args[0])).receive();
    }
}
